<?php
/**
 * Created by PhpStorm.
 * User: longli
 * VX: isa1589518286
 * Date: 2020/11/14
 * Time: 17:10
 * @link http://www.lmterp.cn
 */

namespace app\common\model;

use app\common\status\BaseStatus;

class FinancePayment extends BaseModel
{
    protected $pk = 'payment_id';

    protected $autoWriteTimestamp = 'datetime';

    protected $insert = ['create_by', 'update_by'];

    protected $update = ['update_by'];

    /**
     * 未付款
     * @var int
     */
    const PAY_STATUS_NONE = 0;

    /**
     * 申请付款
     * @var int
     */
    const PAY_STATUS_APPLY = 10;

    /**
     * 部分付款
     * @var int
     */
    const PAY_STATUS_PART = 20;

    /**
     * 全部付款
     * @var int
     */
    const PAY_STATUS_ALL = 30;

    /**
     * 拒付
     * @var int
     */
    const PAY_STATUS_REJECT = 40;

    /**
     * 部分退款
     * @var int
     */
    const PAY_STATUS_RET_PART = 50;

    /**
     * 全部退款
     * @var int
     */
    const PAY_STATUS_RET_ALL = 60;

    /**
     * 取消
     * @var int
     */
    const PAY_STATUS_CANCEL = 70;

    public static $PAY_STATUS = [
        self::PAY_STATUS_NONE => '未付款',
        self::PAY_STATUS_APPLY => '申请付款',
        self::PAY_STATUS_PART => '部分付款',
        self::PAY_STATUS_ALL => '全部付款',
        self::PAY_STATUS_REJECT => '拒付',
        self::PAY_STATUS_RET_PART => '部分退款',
        self::PAY_STATUS_RET_ALL => '全部退款',
        self::PAY_STATUS_CANCEL => '取消',
    ];

    protected function getPayStatusAttr($value)
    {
        return isset(self::$PAY_STATUS[$value]) ? self::$PAY_STATUS[$value] : $value;
    }

    /**
     * 银行转账
     */
    const PAY_TYPE_BANK = 10;

    /**
     * 支付宝
     */
    const PAY_TYPE_ALIPAY = 20;

    /**
     * 现金
     */
    const PAY_TYPE_CASH = 30;

    /**
     * 预付款
     */
    const PAY_TYPE_BEFORE = 40;

    /**
     * 尾款
     */
    const PAY_TYPE_AFTER = 50;

    /**
     * 账期
     */
    const PAY_TYPE_CREDIT = 60;

    /**
     * 款到发货
     */
    const PAY_TYPE_BEFORE_PAYMENT = 70;

    /**
     * 货到付款
     */
    const PAY_TYPE_AFTER_PAYMENT = 80;

    public static $PAY_TYPE = [
        self::PAY_TYPE_BANK     => '银行转账',
        self::PAY_TYPE_ALIPAY   => '支付宝',
        self::PAY_TYPE_CASH     => '现金',
        self::PAY_TYPE_BEFORE   => '预付款',
        self::PAY_TYPE_AFTER    => '尾款',
        self::PAY_TYPE_CREDIT   => '账期',
        self::PAY_TYPE_BEFORE_PAYMENT   => '款到发货',
        self::PAY_TYPE_AFTER_PAYMENT   => '货到付款',
    ];

    protected function getPayTypeAttr($value)
    {
        return isset(self::$PAY_TYPE[$value]) ? self::$PAY_TYPE[$value] : $value;
    }

    protected function getRefTypeAttr($value)
    {
        return isset(BaseStatus::$REF_TYPE[$value]) ? BaseStatus::$REF_TYPE[$value] : $value;
    }

    /**
     * 关联后台用户
     * @return \think\model\relation\BelongsTo
     * @date 2021/01/14
     * @author longli
     */
    public function payUser()
    {
        return $this->belongsTo(Admin::class, "pay_user_id", "id");
    }

    /**
     * 关联附件
     * @return \think\model\relation\HasMany
     * @date 2021/02/08
     * @author longli
     */
    public function attachment()
    {
        return $this->hasMany(SysAttachment::class, 'ref_id', 'payment_id')
            ->where("id_type", self::getTable());
    }

    /**
     * 关联发票配置
     * @return \think\model\relation\BelongsTo
     * @date 2021/01/15
     * @author longli
     */
    public function invoice()
    {
        if($this->is_invoice == self::IS_NO || empty($this->invoice_id)) return null;
        return $this->belongsTo(FinanceInvoiceSetting::class, 'invoice_id', 'invoice_id');
    }

    /**
     * 获取订单总金额
     * @param string $orderSn 订单号
     * @param string $idType 订单号类型
     * @param array $where 自定义条件
     * @return float
     * @date 2020/12/20
     * @author longli
     */
    public static function getTotalMoneyBySn($orderSn, $idType = '', $where = [])
    {
        $model = static::where([
            ["ref_sn", "eq", $orderSn],
            ["pay_status", "neq", self::PAY_STATUS_CANCEL]
        ]);
        if(!empty($idType)) $model->where("ref_id_type", $idType);
        if(!empty($where)) $model->where($where);
        return $model->sum('act_money');
    }

    /**
     * 获取未支付的总额
     * @param string $orderSn 单号
     * @param string $idType id 类型
     * @return float
     * @date 2020/12/20
     * @author longli
     */
    public static function getUnpaidMoney($orderSn, $idType = '')
    {
        return self::getTotalMoneyBySn($orderSn, $idType, ['pay_status' => self::PAY_STATUS_NONE]);
    }

    /**
     * 获取已支付的总额
     * @param string $orderSn 单号
     * @param string $idType id 类型
     * @return float
     * @date 2020/12/20
     * @author longli
     */
    public static function getPaidMoney($orderSn, $idType = '')
    {
        return self::getTotalMoneyBySn($orderSn, $idType, ['pay_status' => [self::PAY_STATUS_ALL, self::PAY_STATUS_PART]]);
    }

    /**
     * 付款单号金额是否存在
     * @param string $orderSn 单号
     * @param float $money 金额
     * @param string $idType id 类型
     * @return bool
     * @date 2020/12/20
     * @author longli
     */
    public static function hasOrderSnMoney($orderSn, $money, $idType = '')
    {
        $model = static::where([
            ["ref_sn", "eq", $orderSn],
            ["act_money", "eq", $money],
            ["pay_status", "neq", self::PAY_STATUS_CANCEL]
        ]);
        if(!empty($idType)) $model->where("ref_id_type", $idType);
        return !!$model->count();
    }

    /**
     * 付款单号是否存在
     * @param string $orderSn 单号
     * @param string $idType id 类型
     * @return bool
     * @date 2020/12/20
     * @author longli
     */
    public static function hasOrder($orderSn, $idType = '')
    {
        $model = static::where([
            ["ref_sn", "eq", $orderSn],
            ["pay_status", "neq", self::PAY_STATUS_CANCEL]
        ]);
        if(!empty($idType)) $model->where("ref_id_type", $idType);
        return !!$model->count();
    }

    /**
     * 取消付款
     * @param string $orderSn 单号
     * @param string $idType id 类型
     * @param string $remark 备注
     * @return bool
     * @date 2020/12/22
     * @author longli
     */
    public static function cancelPayment($orderSn, $idType = '', $remark = '')
    {
        $model = static::where([
            ["ref_sn", "eq", $orderSn]
        ]);
        if(!empty($idType)) $model->where("ref_id_type", $idType);
        $payment = $model->find();
        if(empty($payment) || !in_array($payment->getData('pay_status'), [self::PAY_STATUS_NONE, self::PAY_STATUS_APPLY])) return false;
        $payment->remark .= $remark;
        $payment->pay_status = self::PAY_STATUS_CANCEL;
        $payment->save();
        return true;
    }

}
